home *** CD-ROM | disk | FTP | other *** search
/ Merciful 2 / Merciful - Disc 2.iso / software / a / alliancedoc's03.dms / alliancedoc's03.adf / CHAP7_1.DOC.pp / CHAP7_1.DOC
Text File  |  1992-02-22  |  27KB  |  789 lines

  1.   ________________________________________________________________________
  2.  /                                      \
  3. | ALLIANCE Presents : Amiga Graphics Inside and Out.                   |
  4. |              The complete Book from Abacus.               |
  5. |                                           |
  6. | Typed By          : Razor Blade.                       |
  7. | Supplied By       : Viper.                           |
  8. |                                        |
  9. | ALLIANCE ARE : Alchemist, Aramis, Barbarian, CI/\RS, Chaos, Glitch, Mit, |
  10. |         Raistlin, Razor Blade, ShadowFax and Viper.               |
  11. |                                           |
  12.  \________________________________________________________________________/
  13.  
  14.  
  15. /\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\/\\
  16. >                                      <
  17. >       CALL OUR WORLD HQ N-O-W : UNKNOWN PLEASURES : +44 823 322891      <
  18. >                                      <
  19. \//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//\//
  20.  
  21.  
  22.  
  23.        
  24.        
  25.                      CHAPTER 7 - THE IFF-ILBM STANDARD
  26.                      =================================
  27.        
  28.        
  29. "IFF" is the abbreviation for "Interchange File Format. This format evolved
  30. from an agreement between two companies, Electronic Arts and Commodore when
  31. the Amiga was just being introduced. These companies decided that it would
  32. not be practical for users or programmers if each graphic program saved 
  33. graphics in a different format. If this happened then it is possible that
  34. Graphicraft or Aegis pictures would only work with Aegis software. Without
  35. a
  36. a standard format exchanging pictures between programs would be impossible.
  37. This is the reason why the standard format ILBM (InterLeave BitMap) was
  38. created. An ILBM file consists of many components. The following are the 
  39. most important:
  40.        
  41.            'BMHD' = BitMapHeaDer.
  42.        
  43. Identification: BMHDnnnn
  44.        
  45. Offset  Type     Description.
  46. ------- -------- -----------------------------------------------------
  47. +000    Word     Width of graphic.
  48. +002    Word     Height of graphic.
  49. +004    Word     X position this graphic.
  50. +006    Word     Y position this graphic.
  51. +008    Byte     Number of bitplanes (depth)
  52. +009    Byte     Masking
  53.                  0 = No Masking.
  54.                  1 = MAsking.
  55.                  2 = Transparent.
  56.                  3 = Lasso.
  57. +010    Byte     Data compression.
  58.                  0 = No Compression.
  59.                  1 = ByteRun1 algorithm.
  60. +011    Byte     Unused.
  61. +012    Word     "transparent" colour.
  62. +014    Byte     X aspect.
  63. +015    Byte     Y aspect.
  64. +016    Word     Width of Source Page.
  65. +018    Word     Height of Source Page.
  66.        
  67.        
  68.                             PAGE 279
  69.        
  70. ---------------------------------------------------------------------------
  71.        
  72.        
  73.        "CMAP" = ColorMap
  74.        
  75. Identification: CMAPnnnn
  76.        
  77. Offset  Type    Description
  78. ------- ------- ----------------------------------------------------------
  79. +001    Byte    Red (0-255)
  80. +002    Byte    Green (0-255)
  81. +003    Byte    Blue (0-255)
  82.        
  83.        
  84.        "BODY" = Bit-Planes.
  85.        
  86. Identification: BODYnnn
  87.        
  88. -----------------------------------------------------
  89. Bit-plane 1
  90. Bit-Plane 2
  91. (...)
  92. Bit-Plane n
  93. ------------------------------------------------------
  94.        
  95.     
  96.        "CAMG" = Amiga ViewPort Mode (Hires, lores, Lace, etc...)
  97.        
  98. Identificiation: CAMGnnnn
  99.        
  100. Offset  Type    Description
  101. ------- ------- ------------------------------------------------------
  102. +000    Long    ViewPort Mode (see chapter 4).
  103. ----------------------------------------------------------------------
  104.        
  105. Same as the color cycle information from GraphiCraft:
  106.        
  107.        "CCRT" - raphiCraft ColorCycle Data.
  108.        
  109. Identification: "CCRTnnnn"
  110.        
  111. Offset  Type    Description.
  112. ------- ------- ----------------------------------------------
  113. +000    Word    Direction.
  114.                 0 = Backwards.
  115.                 1 = Forwards.
  116. +002    Byte    Start (number of colour register; 0-31)
  117. +003    Byte    End (number of colour register; 0-31)
  118. +004    Long    Seconds.
  119. +008    Long    Micro Seconds.
  120. ---------------------------------------------------------------
  121.        
  122. These important data blocks represent the ILBM format file for every 
  123. graphic saved using this method.
  124.        
  125. The folowing program demonstrates how to load and display this type of 
  126. file. It is possible for you to load any ILBM graphic that you want. For 
  127. example, you can load a graphic that was created with your drawing program
  128. or an ILBM graphic from any other type of program.
  129.        
  130.        
  131.                             PAGE 280
  132.      
  133. ---------------------------------------------------------------------------
  134.        
  135.        
  136.        '####################################################
  137.        '#
  138.        '# Section: 7
  139.        '# Program: Load ILBM picture from disk.
  140.        '# Date   : 01/15/87
  141.        '# Author : TOB
  142.        '# Version: 1.0
  143.        '#
  144.        '# Loads pictures of any mode, including HAM, halfbrite and
  145.        '# any GraphiCraft Color Cycle.
  146.        '#
  147.        '# Based on ILBM IFF Interleaved Bitmap Standard published November
  148.        '# 15, 1985 in the Rom kenal manual.
  149.        '#
  150.        '#######################################################
  151.        
  152.        PRINT "Searching for .bmap files ........ "
  153.        
  154.        'DOS-library
  155.        DECLARE FUNCTION xOpen& LIBRARY
  156.        DECLARE FUNCTION xRead& LIBRARY
  157.        DECLARE FUNCTION Seek& LIBRARY
  158.        'xClose()
  159.        'Delay()
  160.        
  161.        'EXEC-library
  162.        DECLARE FUNCTION AllocMem& LIBRARY
  163.        DECLARE FUNCTION DoIO% LIBRARY
  164.        DECLARE FUNCTION OpenDevice% LIBRARY
  165.        DECLARE FUNCTION AllocSignal% LIBRARY
  166.        DECLARE FUNCTION FindTask& LIBRARY
  167.        'FreeMem()
  168.        
  169.        'GRAPHICS-library
  170.        DECLARE FUNCTION AllocRaster& LIBRARY
  171.        'SetRast()
  172.        'LoadRGB4()
  173.        
  174.        LIBRARY "dos.library"
  175.        LIBRARY "exec.library"
  176.        LIBRARY "graphics.library"
  177.        
  178.     main: '* LOAD
  179.        
  180.        
  181.                             PAGE 281
  182.        
  183. ---------------------------------------------------------------------------
  184.        
  185.        
  186.        CLS
  187.        PRINT "ILBM Loader"
  188.        PRINT
  189.        PRINT "Loads Standard IFF Graphic Files into"
  190.        PRINT "memory and displays the Picture."       
  191.        PRINT 
  192.        PRINT "The IFF Loader supports GraphiCraft color cycling,"
  193.        PRINT " the display of Hold-and-Modify (4096 colors)"
  194.        PRINT " and Halfbrite (64 colours)."
  195.        PRINT 
  196.        PRINT "In accordance with the ILBM standards it decodes packed"
  197.        PRINT "graphic files that use the ByteRun1 method and "
  198.        PRINT "displays them."
  199.        PRINT
  200.        PRINT "If desired, you can print the picture on a graphics"
  201.        PRINT " capable printer."
  202.        
  203.        LINE INPUT "Name of IBM File : ";ilbm.file$
  204.        LINE INPUT "Do you wantthe picture printed (Y/N) ? ";yn$
  205.        
  206.        LoadILBM ilbm.file$
  207.        ColorCycle -1
  208.        
  209.        IF yn$ = "y" THEN
  210.            WINDOW OUTPUT 2
  211.            Hardcopy
  212.        END IF
  213.        
  214.        WHILE INKEY$ = "":WEND
  215.        ILBMend
  216.        
  217.        LIBRARY CLOSE
  218.        
  219.     
  220.     Sub LoadILBM(ilbm.name$) STATIC
  221.        SHARED disk.handle&, buf.read&
  222.        SHARED buf.color&, but.rgb&
  223.        SHARED ilbm.error$, signal%
  224.        SHARED screen.kolor%, amiga.viewport&
  225.        SHARED ilbm.vp.mode&
  226.        SHARED amiga.rastport&
  227.        
  228.        disk.modeOldFile%  = 1005
  229.        disk.name$         = ilbm.name+CHR$(0)
  230.        
  231.        '* Open ILBM file
  232.        disk.handle& = xOpen&(SADD(disk.name%),1005)
  233.        IF disk.handle& = 0 THEN
  234.        
  235.        
  236.                             PAGE 282
  237.        
  238. ---------------------------------------------------------------------------
  239.        
  240.        
  241.            ilbm.error$ = "ILBM File "+ilbm.name$+" not on specified disk
  242.  and drawer. "
  243.            GOTO ilbm.error.A
  244.        END IF
  245.        
  246.        '* Setup disk read buffer.
  247.        mem.opt& = 2^0+2^16
  248.        buf.size& = 240
  249.        buf.add&  = AllocMem&(buf.size&,mem.opt&)
  250.        IF buf.add& = 0 THEN
  251.            ilbm.error$ = "Not enough buffer memory free."
  252.            GOTO ilbm.error.A
  253.        END IF
  254.        
  255.        '* Section buffer for chunk areas.
  256.        buf.read& = buf.add&+0*120
  257.        buf.rgb&  = buf.add&+1*120
  258.        
  259.        '* Is it an ILBM file ???
  260.        disk.wasread& = xRead&(disk.handle&,buf.read&,12)
  261.        ilbm.ID.$ = ""
  262.        FOR loop1% = 8 TO 11
  263.            ilbm.ID.$ = ilbm.ID.$ + CHR$(PEEK,buf.read&+loop1%))
  264.        NEXT loop1%
  265.        
  266.        IF ilbm.ID.$ <> "ILBM" THEN
  267.            ilbm.error$ = "File ":+ilbm.name$+" is not an ILBM file."
  268.            GOTO ilbm.error.A
  269.        END IF
  270.        
  271.        '* read data chunks from ILBM 
  272.        WHILE (signal%<>1) AND (ilbm.error$ = "")
  273.            ReadChunk
  274.        WEND
  275.        
  276.        '* Error ? 
  277.    ilbm.error.A:
  278.        IF ilbm.error$<>"" THEN
  279.            WINDOW CLOSE 2
  280.            SCREEN CLOSE 1
  281.            PRINT ilbm.error$
  282.            EXIT SUB
  283.        END IF
  284.        
  285.        '* All ok
  286.        CALL LoadRGB4(amiga.viewport&, buf.rgb&, screen.kolor%)
  287.        
  288.        '* Close ILBM file?
  289.        IF disk.handle & <> 0 THEN
  290.            CALL xClose(disk.handle&)
  291.        END IF
  292.        IF buf.add& <> 0 THEN
  293.            CALL FreeMem(buf.add&,buf.size&)
  294.        
  295.        
  296.                             PAGE 283
  297.        
  298. ---------------------------------------------------------------------------
  299.        
  300.        
  301.            buf.add& = 0
  302.        END IF
  303.        
  304.        '* Set ViewModes.
  305.         POKEW amiga.viewport&+32, ilbm.vp.mode&
  306.    END SUB
  307.        
  308.    SUB ILBMend STATIC
  309.        WINDOW CLOSE 2
  310.        SCREEN CLOSE 1
  311.    END SUB
  312.        
  313.    SUB ColorCycle(mode%) STATIC
  314.        SHARED ccrt.direction%
  315.        SHARED ccrt.start%, amiga.colortable&
  316.        SHARED ccrt.end%, screen.kolor%
  317.        SHARED ccrt.secs&, status%
  318.        SHARED ccrt.mics&, amiga.viewport&
  319.        
  320.        '* As intended.
  321.        IF (status% AND 2^4) <> 2^4 THEN
  322.            EXIT SUB
  323.        END IF
  324.        
  325.        '* Setup varaible field
  326.        DIM kolor.original%(screen.kolor%-1)
  327.        DIM kolor.actual%(screen.kolor%-1)
  328.        
  329.        '* all OK, save old color from ViewPort.
  330.        FOR loop1% = 0 TO screen.kolor%-1
  331.            kolor.original%(loop1%) = PEEKW(amiga.colortable&+2*loop1%)
  332.            kolor.actual%(loop1%) = kolor.original%(loop1%)
  333.        NEXT loop1%
  334.        
  335.        '* Colour cycling.
  336.        WHILE mode%<>0
  337.            '* Mode ?
  338.            IF mode% < 0 THEN
  339.                in$ = INKEY$
  340.                IF in$<>"" THEN mode% = 0
  341.            ELSE
  342.                mode% = mode% - 1
  343.            END IF
  344.            
  345.            '* Forwards ?
  346.            IF ccrt.direction% = 1 THEN
  347.                ccrt.backup% = kolor.actual%(ccrt.start%)
  348.                FOR loop1% = ccrt.start%+1 TO ccrt.end%
  349.                    kolor.actual%(loop1%-1)=kolor.actual%(loop1%)
  350.                NEXT loop1%
  351.                kolor.actual%(ccrt.end%) = ccrt.backup%
  352.        
  353.            '* Backwards.
  354.            ELSE
  355.        
  356.        
  357.                             PAGE 284
  358.        
  359. ---------------------------------------------------------------------------
  360.        
  361.        
  362.                ccrt.backup% = kolor.actual%(ccrt.end%)
  363.                FOR loop1% = ccrt.start%-1 TO ccrt.end% STEP -1
  364.                    kolor.actual%(loop1%+1) = kolor.actual%(loop1%)
  365.                NEXT loop1%
  366.                kolor.actual%(ccrt.start%) = ccrt.backup%
  367.            END IF
  368.            
  369.            CALL LoadRGB4(amiga.viewport&,VARPTR(kolor.actual%(0)),
  370.   screen.kolor%)
  371.            timeout& = 50*(ccrt.secs&+(ccrt.mics&/1000000&))
  372.            CALL Delay(timeout&)
  373.        WEND
  374.        
  375.        '* Restore original colors.
  376.        CALL LoadRGB4(amiga.viewport&,VARPTR(kolor.original%(0)),screen.kolor%)
  377.            
  378.        '* REturn fields.
  379.        ERASE kolor.original%
  380.        ERASE kolor.actual%
  381.   END SUB
  382.        
  383.    SUB ReadChunk STATIC
  384.        SHARED disk.handle&, buf.read&
  385.        SHARED buf.color&, buf.rgb&
  386.        SHARED ilbm.error$, signal%
  387.        SHARED screen.kolor%, amiga.viewport&
  388.        SHARED ilbm.vp.mode&, status%
  389.        SHARED amiga.rastport&
  390.        SHARED ccrt.direction%
  391.        SHARED ccrt.start%, amiga.colortable&
  392.        SHARED ccrt.end%, screen.kolor%
  393.        SHARED ccrt.secs&
  394.        SHARED ccrt.mics&
  395.        
  396.        '* Read chunk header.
  397.        disk.wasread& = xRead&(disk.handle&, buf.read&, 8)
  398.        ilbm.chunk& = PEEKL(buf.read&+4)
  399.        ilbm.ID.$ = ""
  400.        FOR loop1% = 0 TO 3
  401.            ilbm.ID.$ = ilbm.ID.$+CHR$(PEEK(buf.read&+loop1%))
  402.        NEXT loop1%
  403.        
  404.        '* The bitmap Header (BMHD) ? 
  405.        IF ilbm.ID.$ = "BMHD" THEN
  406.            '* Read chunk contents.
  407.            disk.wasread& = xRead&(disk.handle&,buf.read&,ilbm.chunk&)
  408.        
  409.            status% = status% OR 2^0
  410.            ilbm.width% = PEEKW(buf.read&+0)
  411.            ilbm.height% = PEEKW(buf.read&+2)
  412.            ilbm.depth% = PEEK(buf.read&+8)
  413.            ilbm.mode%  = PEEK(buf.read&+10)
  414.        
  415.        
  416.                             PAGE 285
  417.        
  418. ---------------------------------------------------------------------------
  419.        
  420.        
  421.            screen.width& = PEEKW(buf.read&+16)
  422.            screen.height% = PEEKW(buf.read&+18)
  423.            
  424.            '* Build Display Parameters.
  425.            ilbm.bytes% = ilbm.width%/8
  426.            screen.bytes% = screen.width%/8
  427.            screen.kolor% = 2^(ilbm.depth%)
  428.            
  429.            '* prepare for our display.
  430.        
  431.            '* Hires (Hi resolution ? )
  432.            IF screen.width%>320 THEN
  433.                screen.mode% = 2
  434.            ELSE
  435.                screen.mode% = 1
  436.            END IF
  437.            
  438.            '* Interlace (y = 0 - 399)
  439.            IF screen.height%>200 THEN screen.mode% = screen.mode%+2
  440.            
  441.            '* ILBM depth% = 6 -> HAM/Halfbrite ?
  442.            IF ilbm.depth% = 6 THEN 
  443.                ilbm.re% = -1
  444.            END IF
  445.            
  446.            depth% = ilbm.depth%+ilbm.reg%
  447.            SCREEN 1,screen.width%,screen.height%,depth%,screen.mode%
  448.            WINDOW 2,,,0,1
  449.            
  450.            '* System parameters
  451.            amiga.windo&          = WINDOW(7)
  452.            amiga.screen&         = PEEKL(amiga.windo&+46)
  453.            amiga.viewport&       = amiga.screen&+44
  454.            amiga.rastport&       = amiga.screen&+84
  455.            amiga.colormap&       = PEEKL(amiga.viewport&+4)
  456.            amiga.colortable&     = PEEKL(amiga.colormap&+4)
  457.            amiga.bitmap&         = PEEKL(amiga.rastport&+4)
  458.            FOR loop1% = 0 TO ilbm.depth%-1
  459.                amiga.plane&(loop1%) = PEEKL(amiga.bitmap&+8+loop1%*4)
  460.            NEXT loop1%
  461.            
  462.            '* For HAM/Halfbrite prepare 6 bitplanes.
  463.            IF ilbm.reg% = -1 THEN
  464.                ilbm.reg% = 0
  465.                newplane& = ALlocRaster&(screen.width%,screen.height%)
  466.                IF newplane& = 0 THEN
  467.                    ilbm.error$ = "Not enough memory free for 6 bitplanes!"
  468.                ELSE
  469.                    POKE amiga.bitmap&+5,6
  470.                    POKEL amiga.bitmap&+28,newplane&
  471.                END IF
  472.            
  473.            
  474.                                PAGE 286
  475.        
  476. ---------------------------------------------------------------------------
  477.        
  478.        
  479.            END IF
  480.            
  481.            ;* ColorTable (CMAP)?
  482.        ELSE IF ilbm.ID.$ = "CMAP" THEN
  483.            '* REad chunk contents.
  484.            disk.wasread& = xRead&(disk.handle&,buf.read&,ilbm.chunk&)
  485.            status = status% OR 2^1
  486.            
  487.            '* Calculate RGB table.
  488.            FOR loop1% = 0 TO screen.kolor% - 1
  489.                kolor.red% = PEEK(buf.read&+loop1%*3+0)
  490.                kolor.green%=PEEK(buf.read&+loop1%*3+1)
  491.                kolor.blue% =PEEK(buf.read&+loop1%*3+2)
  492.                kolor.rgb%  = kolor.green%+16*kolor.red%+1/16*kolor.blue%
  493.                POKEW buf.rgb&+2*loop1%,kolor.rgb%
  494.            NEXT loop1%
  495.        
  496.            '* Alignment.
  497.            IF (ilbm.chunk OR 1)=ilbm.chunk THEN
  498.                disk.wasread&=xRead&(disk.handle&,buf.read&,1)
  499.            END IF
  500.            
  501.            '* Viewport Mode (CAMG) AMIGA ? 
  502.        ELSE IF
  503.        ELSE IF ilbm.ID.$ = "CAMG" THEN
  504.            '* Read chunk contents.
  505.            disk.wasread& = xRead&(disk.handle&, buf.read&, ilbm.chunk&)
  506.            
  507.            status% = status% OR 2^4
  508.            ccrt.direction%   = PEEKW(buf.read&+0)
  509.            ccrt.start%       = PEEK (buf.read&+2)
  510.            ccrt.end%         = PEEK (buf.read&+3)
  511.            ccrt.secs&        = PEEKL (buf.read&+4)
  512.            ccrt.mics&        = PEEKL(buf.read&+8)
  513.            
  514.        '* Bitplanes (BODY) ?
  515.        ELSEIF ilbm.ID.$ = "BODY" THEN
  516.            status% = status% OR 2^2
  517.            
  518.            '* not compressed data.
  519.            IF ilbm.mode% = 0 THEN
  520.                FOR loop1% = 0 TO ilbm.height%-1
  521.                    FOR loop2% = 0 TO ilbm.depth%-1
  522.        
  523.        
  524.                             PAGE 287
  525.        
  526. ---------------------------------------------------------------------------
  527.        
  528.        
  529.                        screen.buffer& =amiga.plane&(loop2%)+(loop1%*
  530.   screen.bytes%)
  531.                        disk.wasread& = xRead&(disk.handle&,screen.buffer&,
  532.   ilbm.bytes%)
  533.                    NEXT loop2%
  534.                NEXT loop1%
  535.            
  536.            '* Compressed Data (ByteRun1-Encoding)
  537.            ELSEIF ilbm.mode% = 1 THEN
  538.                FOR loop1% = 0 TO ilbm.height%-1
  539.                    FOR loop2% = 0 TO ilbm.depth%-1
  540.                        screen.buffer& = amiga.plane&(loop2%)+(loop1%*
  541.  screen.bytes%)
  542.                        counter% = 0
  543.            
  544.                        '* Decoding.
  545.                        WHILE counter% <ilbm.bytes%
  546.                            disk.wasread& = xRead&(disk.handle&,buf.read&,1)
  547.                            code%  = PEEK(buf.read&)
  548.                            '* Code 1: read n bytes uncoded.
  549.                            IF code% < 128 THEN
  550.                               disk.wasread& = 
  551.   xRead&(disk.handle&,screen.buffer&+counter%,code%+1)
  552.                                counter% = counter%+code%+1
  553.                            '* Code 2 Repeat bytes (257-n) times.
  554.                            ELSEIF code% > 128 THEN
  555.                                disk.wasread& = xRead&(disk.handle&,buf.read&,1)
  556.                                disk.byte% = PEEK(buf.read%)
  557.                                FOR loop3% = counter% TO counter%+257-code%
  558.                                    POKE screen.buffer&+loop3%,disk.byte%
  559.                                NEXT loop3%
  560.                                counter% = counter%+257-code%
  561.                            '* Code 3 : no operation.
  562.                            ELSE 
  563.                                '* no operation.
  564.                            END IF
  565.                        WEND
  566.                    NEXT loop2%
  567.                NEXT loop1%
  568.            '* Different decoding method.
  569.            ELSE 
  570.                ilbm.error$ = "Data compression algorithm unknown. "
  571.            END IF
  572.        '* Process unimportant chunks. (GRAB, DEST, SPRT, etc...)
  573.        ELSE
  574.            ;* Read straigh count bytes.
  575.            IF (ilbm.chunk% OR 1)=ilbm.chunk% THEN
  576.                ilbm.chunk%=lib.chunk%+1
  577.            
  578.            
  579.                             PAGE 288
  580.        
  581. ---------------------------------------------------------------------------
  582.        
  583.        
  584.            END IF
  585.        
  586.        '*Move Disk cursor.
  587.        mode.current% = 0
  588.        stat& = Seek&(disk.handle&,ilbm.chunk%,0)
  589.        IF stat& = -1 THEN
  590.            ilbm.error = "DOS error. Seek() failed."
  591.        END IF
  592.        
  593.        END IF
  594.        
  595.        '* Error check.
  596.        IF disk.wasread& < - THEN
  597.            ilbm.error$ = "DOS Error. Read() Failed."
  598.        '* EOF (end of file) reached ?
  599.        ELSEIF disk.wasread& = 0 AND ((status% AND 7) <> 7 THEN
  600.            ilbm.error$ = "ILBM data chunks not present."
  601.            signal% = 1
  602.        ELSEIF (status% AND 7) = 7 THEN
  603.            signal% = 1
  604.        END IF
  605.    END SUB
  606.        
  607.        
  608.     SUB Hardcopy STATIC
  609.            mem.opt& = 2^0+2^16
  610.            p.io&    = AllocMem&(100,mem.opt&)
  611.            p.port&  = p.io&+62
  612.            IF p.io& = 0 THEN ERROR 7
  613.            
  614.            f.windo&        = WINDOW(7)
  615.            f.rastport&     = PEEKL(f.windo&+50)
  616.            f.width%        = PEEKW(f.windo&+112)
  617.            f.height%       = PEEKW(f.windo&+114)
  618.            f.screen&       = PEEKL(f.windo&+46)
  619.            f.viewport&     = f.screen&+44
  620.            f.colormap&     = PEEKL(f.viewport&+4)
  621.            f.vp.mode%      = PEEKW(f.viewport&+32)
  622.            
  623.            
  624.            p.sigBit% = AllocSignal%(-1)
  625.            IF p.sigBit% = -1 THEN
  626.                PRINT "No Signalbit free!"
  627.                CALL FreeMem(p.io&,100)
  628.                EXIT SUB
  629.            END IF
  630.            p.sigTask& = FindTask&(0)
  631.            
  632.            POKE p.port&+8,4
  633.            POKE p.port&+10,p.port&+34
  634.            POKE p.port&+15,p.sigBit%
  635.            POKEL p.port&+16,p.sigTask&
  636.            POKEL p.port&+20,p.port&+24
  637.        
  638.        
  639.                                PAGE 289
  640.        
  641. ---------------------------------------------------------------------------
  642.        
  643.        
  644.            POKEL p.port&+28,p.port&+20
  645.            POKE  p.port&+34,ASC("P")
  646.            POKE  p.port&+35,ASC("R")
  647.            POKE  p.port&+36,ASC("T")
  648.            
  649.            CALL AddPort(p.port&)
  650.            
  651.            POKE  p.io&+8,5
  652.            POKEL p.io&+14,p.port&
  653.            POKEW p.io&+28,11
  654.            POKEL p.io&+32,f.rastport&
  655.            POKEL p.io&+36,f.colormap&
  656.            POKEL p.io&+40,f.vp.mode%
  657.            POKEW p.io&+48,f.width%
  658.            POKEW p.io&+50,f.height%
  659.            POKEL p.io&+52,f.width%
  660.            POKEL p.io&+56,f.height%
  661.            POKEW p.io&+60,4
  662.        
  663.            d.name$ = "printer.device"+CHR$(0)
  664.            status% = OpenDevice%(SADD(d.name$),0,p.io&,0)
  665.            IF status% <> 0 THEN
  666.                PRINT "Printer is not free":
  667.                CALL FreeMem(p.io&,100)
  668.                CALL FreeSignal(p.sigBit%)
  669.                EXIT SUB
  670.            END IF
  671.            
  672.            ercond% = DoIO%(p.io&)
  673.            
  674.            CALL CloseDevice(p.io&)
  675.            CALL RemPort(p.port&)
  676.            CALL FreeMem(p.io&,100)
  677.            CALL FreeSignal(p.sigBit%)
  678.            PRINT "Error Code: ";ercond%
  679.        END SUB
  680.        
  681.        
  682. PROGRAM DESCRIPTION.
  683. ====================
  684.        
  685. The SUB program LoadILBM requires a string containing the name of the ILBM
  686. picture you want to load from disk. The picture must be in the active disk
  687. directory in order for the active program to find it (CHDIR directory). The
  688. Extras diskette for workbench 1.2 contains the Heart.ILBM file, which is 
  689. a good example picture to use. This program loads and displays the picture.
  690. Now you could call the SUB program ColorCycle. When this program finds a 
  691. CCRT ColorCycle data block, it activates the cycling, which creates a 
  692. motion like effect on the screen. This SUB program requires an integer 
  693. argument. If the argument is negative, the Amiga cycles the colours until 
  694. you press a key. If the argument is positive, the Amiga cycles the colors 
  695. for a time period determined by your argument. The SUB program ILBMend
  696. stops the display and closes both the screen and window.
  697.        
  698.        
  699.                                PAGE 290
  700.        
  701. ------------------------------------------------------------------------
  702.        
  703.        
  704. The DOS library routines are new in our program. You cannot use the built 
  705. in OPEN/INPUT#/CLOSE commands when working with ILBM files because these 
  706. commands place zeros in the data. Here is a short explanation of the DOS
  707. routines used:
  708.        
  709.        name$ = name$+CHR$(0)
  710.        disk.handle&=xOpen&(SADD(name$),1005)
  711.            
  712.         name$  : Name of file to be opened.
  713.         1005   : ModeOldFile - file already exists.
  714.         1006   : ModeNewFile - make file with this name.
  715.         dis.handle& = BPTR (pointer/4) in handler data block when 0, then
  716.                       xOpen failed.
  717.        
  718.        
  719.                         =================================
  720.        
  721.         wasread& = xRead(disk.handle&,buffer&,bytes&)
  722.        
  723.         disk.handle& : Address from xOpen call.
  724.         buffer&      : Address of a free memory area.
  725.         bytes&       : Number of bytes to be read from the actual disk
  726.                        cursor position that have to fit in the buffer!
  727.         wasread&     : Number of bytes read.
  728.                        =0: EOF (End Of File)
  729.                        smaller than zero: read error.
  730.        
  731.        
  732.                         ======================================
  733.        
  734.          oldpos& = Seek(disk.handle&,offset%,mode%)
  735.            
  736.          disk.handle&  : Address from xOpen call.
  737.          offset%       : Number of bytes to move the disk cursor.
  738.          mode%         : 0 = From current position.
  739.                         -1 = From file begin.
  740.                          1 = From file end.
  741.        
  742.        
  743.                          ======================================
  744.        
  745.          CALL xClose(disk.handle&)
  746.            
  747.          disk.handle& : Handle from xOpen command; closes file.
  748.          
  749.        
  750.                           =======================================
  751.        
  752.          CALL delay(ticks)
  753.            
  754.           tick  : 1/50/ second.
  755.           microseconds : 1/100000 second.
  756.        
  757. Waits for the specified time (however, this does not mean busy waiting, 
  758. the system has additional computing time free).
  759.        
  760.        
  761.                             PAGE 291
  762.        
  763. ---------------------------------------------------------------------------
  764.        
  765.        
  766. Special Features of the program:
  767. -------------------------------
  768.        
  769. This program not only supports the AmigaBASIC display modes hires and 
  770. interlace, but also the ILBM graphics in halfbrite (64 colors) and HAM mode
  771. (4096) colours. Both modes use six bitplanes. Whenever one of these modes 
  772. is encountered, a sixth bitplane is added to the screen. However, we do not
  773. clear this bitplane using FreeRaster. Instead, when the SCREEN CLOSE 
  774. statement closes the new screen, all the bitplanes, including the sixth
  775. bitplane that was added are automatically deleted.
  776.        
  777. The program is capable of decoding compacted bitplanes by using the 
  778. "ByteRun1" method. This method uses two control codes. When the first byte
  779. read is smaller than 128 then the following byte is simply loaded and used.
  780. When the first byte is a value greater than 128, the second byte is 
  781. repeated 257 times (normally signed bytes from -127 to +128 are used for a 
  782. more complicated compression algorithm). When the byte is equal to 128 
  783. nothing happens because it has a NOP (No Operation).
  784.        
  785.        
  786.                             PAGE 292
  787.        
  788. ---------------------------------------------------------------------------
  789.